package com.wtao.imagereader.utils;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.core.VideoCapture;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleOwner;

import com.google.common.util.concurrent.ListenableFuture;

import java.io.File;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;

public class CameraXHelper implements ImageAnalysis.Analyzer {
    private static final String TAG = "CameraXHelper";

    private Activity mActivity;
    ProcessCameraProvider mCameraProvider;
    private ImageCapture imageCapture;
    private VideoCapture videoCapture;
    private PreviewView mPreviewView;
    private boolean mNeedCapture;
    public static final String PUBLIC_FOLDER = "senseauto";
    private static int vName = 0;

    public CameraXHelper(Activity activity, PreviewView previewView) {
        this.mActivity = activity;
        this.mPreviewView = previewView;
    }

    public void init(int cameraid) {
        ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(mActivity);
        cameraProviderFuture.addListener(() -> {
            try {
                mCameraProvider = cameraProviderFuture.get();
                startCameraX(cameraid);
            } catch (ExecutionException | InterruptedException e) {
                Log.e(TAG, "init: " + e.getMessage());
                e.printStackTrace();
            }
        }, getExecutor());
    }

    Executor getExecutor() {
        return ContextCompat.getMainExecutor(mActivity);
    }

    @SuppressLint("RestrictedApi")
    private void startCameraX(int id) {
//            getCameList()
        mCameraProvider.unbindAll();
        CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(id).build();
        if (cameraSelector == null) Log.e(TAG, "startCameraX: " + cameraSelector.getLensFacing());
        Preview preview = new Preview.Builder().build();
        preview.setSurfaceProvider(mPreviewView.getSurfaceProvider());

        videoCapture = new VideoCapture.Builder().build();

        Camera camera = mCameraProvider.bindToLifecycle((LifecycleOwner) mActivity, cameraSelector, preview, videoCapture);
        if (camera != null)
            Log.e(TAG, "startCameraX: " + camera.getCameraInfo().getImplementationType());

    }

    @Override
    public void analyze(@NonNull ImageProxy image) {
        // image processing here for the current frame
        Log.d("TAG", "analyze: got the frame at: " + image.getImageInfo().getTimestamp());
        Log.d("TAG", "analyze: image.getFormat() = " + image.getFormat());
    }

    public void switchCamera(int id) {
        startCameraX(id);
    }

    public static File getTestImageDir(Context context) {
        File dir = new File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), PUBLIC_FOLDER);
//            File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        return dir;
    }

    public static File getOutputVideoFile(Context context) {
        File file = getTestImageDir(context);
//            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINESE).format(new Date());
//            File mediaFile = new File(file.getPath() + File.separator + "VIDEO_" + timeStamp + ".mp4");
        File mediaFile = new File(file.getPath() + File.separator + "VIDEO_" + String.valueOf(vName++) + ".mp4");
        Log.e("DebugDirPath", file.getPath());
        return mediaFile;
    }

    public void showFolderClick() {
        File file = getTestImageDir(mActivity);
        Toast.makeText(mActivity, "保存路径:" + file.getPath(), Toast.LENGTH_LONG).show();
    }

    @SuppressLint({"MissingPermission", "RestrictedApi"})
    public void startRecordingVideo() {
        if (videoCapture != null) {
            File file = getOutputVideoFile(mActivity);
            try {
                if (ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
                    // TODO: Consider calling ActivityCompat#requestPermissions
                    // here to request the missing permissions, and then overriding
                    //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                    //                                          int[] grantResults)
                    // to handle the case where the user grants the permission. See the documentation
                    // for ActivityCompat#requestPermissions for more details.
                    return;
                }
                videoCapture.startRecording(new VideoCapture.OutputFileOptions.Builder(file).build(), getExecutor(), new VideoCapture.OnVideoSavedCallback() {
                            @Override
                            public void onVideoSaved(@NonNull VideoCapture.OutputFileResults outputFileResults) {
                                Toast.makeText(mActivity, "视频保存成功！", Toast.LENGTH_SHORT).show();
                            }

                            @Override
                            public void onError(int videoCaptureError, @NonNull String message, @Nullable Throwable cause) {
                                Toast.makeText(mActivity, "视频保存失败！ " + message, Toast.LENGTH_SHORT).show();
                            }
                        }
                );
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    @SuppressLint("RestrictedApi")
    public void stopRecordingVideo() {
        if (null != videoCapture) {
            videoCapture.stopRecording();
        }
    }

    public void release() {
        if (mCameraProvider != null) {
            mCameraProvider.unbindAll();
        }
    }

}